package com.itheima.tlias.aspect;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;

/**
 * 计算耗时切面类
 *
 * @Author mr.luo
 * @Date 16 4月 2025 15:24
 */
@Slf4j
//@Aspect
//@Component
public class CostTimeAspect {
    @Pointcut("execution(* com.itheima.tlias.service.*.*(..))")  //切入点
//    @Pointcut("execution(* com.itheima.tlias.service.impl.EmpServiceImpl.*(..))")  //切入点
//    @Pointcut("execution(* com.itheima.tlias.service.impl.EmpServiceImpl.*List*(..))")  //切入点
    public void pt() {
    }
//只有环绕通知必须调用原始方法，并且需要返回原始方法的结果，并且形参列表的参数是ProceedingJoinPoint
//    并且原石方法如果抛异常，原始方法后执行的逻辑不会再执行


    @Before("pt()")
    public void before(JoinPoint joinPoint) {
        log.info("[Before]原始方法执行前执行的，不受原始方法异常的影响");
    }

    @Around("pt()")
    public Object CostTime(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        log.info("[Around]原始方法执行前执行的");
        //1.原始方法执行前开始计时
        long start = System.currentTimeMillis();
        //2.调用原始方法
        Object result = proceedingJoinPoint.proceed();
        //3.原始方法执行后执行，计时
        log.info("[Around]原始方法执行前执行的，受原始方法异常的影响");
        long end = System.currentTimeMillis();
        //4.计算耗时
        log.info("原始方法耗时,{},毫秒", (end - start));
        //5.将原始方法的结果返回
        return result;
    }


    @After("pt()")
    public void after(JoinPoint joinPoint) {
        log.info("[After]原始方法执行后执行的，不受原始方法异常的影响");
    }

    @AfterReturning("pt()")
    public void afterReturning(JoinPoint joinPoint) {
        log.info("[AfterReturning]原始方法执行后执行的，原始方法没有异常才会执行");
    }

    @AfterThrowing("pt()")
    public void afterThrowing(JoinPoint joinPoint) {
        log.info("[AfterThrowing]原始方法执行后执行的，原始方法有异常才会执行");
    }

}
